Pythonã®astã¢ãžã¥ãŒã«ã«ããæœè±¡æ§ææšæäœã®åãæ¢æ±ããŸããPythonã³ãŒããããã°ã©ã ã§åæãä¿®æ£ãçæããæ¹æ³ãåŠã³ãŸãããã
Python Astã¢ãžã¥ãŒã«ïŒæœè±¡æ§ææšæäœã®è§£èª¬
Pythonã®ast
ã¢ãžã¥ãŒã«ã¯ãPythonã³ãŒãã®æœè±¡æ§ææšïŒASTïŒãæäœãã匷åãªæ¹æ³ãæäŸããŸããASTã¯ãœãŒã¹ã³ãŒãã®æ§ææ§é ãããªãŒåœ¢åŒã§è¡šçŸãããã®ã§ãããã°ã©ã ã§Pythonã³ãŒããåæãä¿®æ£ãããã«ã¯çæããããšãã§ããŸããããã«ãããã³ãŒãåæããŒã«ãèªåãªãã¡ã¯ã¿ãªã³ã°ãéçåæãããã«ã¯ã«ã¹ã¿ã èšèªæ¡åŒµãªã©ãããŸããŸãªã¢ããªã±ãŒã·ã§ã³ãžã®æãéãããŸãããã®èšäºã§ã¯ãast
ã¢ãžã¥ãŒã«ã®åºæ¬ã解説ããå®çšçãªäŸãšãã®æ©èœã«é¢ããæŽå¯ãæäŸããŸãã
æœè±¡æ§ææšïŒASTïŒãšã¯ïŒ
ast
ã¢ãžã¥ãŒã«ã«å
¥ãåã«ãæœè±¡æ§ææšãšã¯äœããçè§£ããŸããããPythonã€ã³ã¿ããªã¿ãã³ãŒããå®è¡ãããšããæåã®ã¹ãããã¯ã³ãŒããASTã«è§£æããããšã§ãããã®ããªãŒæ§é ã¯ã颿°ãã¯ã©ã¹ãã«ãŒããåŒãæŒç®åãªã©ãã³ãŒãã®æ§æèŠçŽ ãšãã®é¢ä¿ã衚ããŸããASTã¯ã空çœãã³ã¡ã³ããªã©ã®ç¡é¢ä¿ãªè©³çްãç Žæ£ããæ¬è³ªçãªæ§é æ
å ±ã«çŠç¹ãåœãŠãŸãããã®ããã«ã³ãŒãã衚çŸããããšã§ãããã°ã©ã èªäœãã³ãŒããåæããã³æäœã§ããããã«ãªããå€ãã®ç¶æ³ã§éåžžã«åœ¹ç«ã¡ãŸãã
ast
ã¢ãžã¥ãŒã«å
¥é
ast
ã¢ãžã¥ãŒã«ã¯Pythonã®æšæºã©ã€ãã©ãªã®äžéšã§ããããã远å ã®ããã±ãŒãžãã€ã³ã¹ããŒã«ããå¿
èŠã¯ãããŸãããã€ã³ããŒãããã ãã§äœ¿ãå§ããããšãã§ããŸãã
import ast
ast
ã¢ãžã¥ãŒã«ã®ã³ã¢æ©èœã¯ast.parse()
ã§ãPythonã³ãŒãã®æååãå
¥åãšããŠåãåããASTãªããžã§ã¯ããè¿ããŸãã
code = """
def add(x, y):
return x + y
"""
ast_tree = ast.parse(code)
print(ast_tree)
ããã¯æ¬¡ã®ãããªãã®ãåºåããŸãïŒ<_ast.Module object at 0x...>
ããã®åºåã¯ç¹ã«æçã§ã¯ãããŸããããã³ãŒããASTã«æ£åžžã«è§£æãããããšã瀺ããŠããŸããast_tree
ãªããžã§ã¯ãã«ã¯ãè§£æãããã³ãŒãå
šäœã®æ§é ãå«ãŸããŠããŸãã
ASTã®æ¢çŽ¢
ASTã®æ§é ãçè§£ããããã«ãast.dump()
颿°ã䜿çšã§ããŸãããã®é¢æ°ã¯ããªãŒãååž°çã«ãã©ããŒã¹ããåããŒãã®è©³çްãªè¡šçŸãåºåããŸãã
code = """
def add(x, y):
return x + y
"""
ast_tree = ast.parse(code)
print(ast.dump(ast_tree, indent=4))
åºåã¯æ¬¡ã®ããã«ãªããŸãã
Module(
body=[
FunctionDef(
name='add',
args=arguments(
posonlyargs=[],
args=[
arg(arg='x', annotation=None, type_comment=None),
arg(arg='y', annotation=None, type_comment=None)
],
kwonlyargs=[],
kw_defaults=[],
defaults=[]
),
body=[
Return(
value=BinOp(
left=Name(id='x', ctx=Load()),
op=Add(),
right=Name(id='y', ctx=Load())
)
)
],
decorator_list=[],
returns=None,
type_comment=None
)
],
type_ignores=[]
)
ãã®åºåã¯ãã³ãŒãã®éå±€æ§é ã瀺ããŠããŸãã詳ããèŠãŠãããŸãããã
Module
ïŒã¢ãžã¥ãŒã«å šäœã衚ãã«ãŒãããŒããbody
ïŒã¢ãžã¥ãŒã«å ã®ã¹ããŒãã¡ã³ãã®ãªã¹ããFunctionDef
ïŒé¢æ°å®çŸ©ã衚ããŸãããã®å±æ§ã«ã¯ä»¥äžãå«ãŸããŸããname
ïŒé¢æ°åïŒ'add'ïŒãargs
ïŒé¢æ°ã®åŒæ°ãarguments
ïŒé¢æ°ã®åŒæ°ã«é¢ããæ å ±ãå«ãŸããŠããŸããarg
ïŒåäžã®åŒæ°ïŒäŸïŒ'x'ã'y'ïŒã衚ããŸããbody
ïŒé¢æ°ã®æ¬äœïŒã¹ããŒãã¡ã³ãã®ãªã¹ãïŒãReturn
ïŒreturnã¹ããŒãã¡ã³ãã衚ããŸããvalue
ïŒè¿ãããå€ãBinOp
ïŒäºé æŒç®ïŒäŸïŒx + yïŒã衚ããŸããleft
ïŒå·Šãªãã©ã³ãïŒäŸïŒ'x'ïŒãop
ïŒæŒç®åïŒäŸïŒ'Add'ïŒãright
ïŒå³ãªãã©ã³ãïŒäŸïŒ'y'ïŒã
ASTã®ãã©ããŒã¹
ast
ã¢ãžã¥ãŒã«ã¯ãASTããã©ããŒã¹ããããã®ast.NodeVisitor
ã¯ã©ã¹ãæäŸããŸããast.NodeVisitor
ããµãã¯ã©ã¹åãããã®ã¡ãœããããªãŒããŒã©ã€ãããããšã§ããã©ããŒã¹äžã«ç¹å®ã®ããŒãã¿ã€ããåŠçã§ããŸããããã¯ãã³ãŒãæ§é ã®åæãç¹å®ã®ãã¿ãŒã³ã®èå¥ããŸãã¯æ
å ±ã®æœåºã«åœ¹ç«ã¡ãŸãã
import ast
class FunctionNameExtractor(ast.NodeVisitor):
def __init__(self):
self.function_names = []
def visit_FunctionDef(self, node):
self.function_names.append(node.name)
code = """
def add(x, y):
return x + y
def subtract(x, y):
return x - y
"""
ast_tree = ast.parse(code)
extractor = FunctionNameExtractor()
extractor.visit(ast_tree)
print(extractor.function_names) # Output: ['add', 'subtract']
ãã®äŸã§ã¯ãFunctionNameExtractor
ã¯ast.NodeVisitor
ããç¶æ¿ããvisit_FunctionDef
ã¡ãœããããªãŒããŒã©ã€ãããŸãããã®ã¡ãœããã¯ãASTå
ã®å颿°å®çŸ©ããŒãã«å¯ŸããŠåŒã³åºãããŸãããã®ã¡ãœããã¯ã颿°åãfunction_names
ãªã¹ãã«è¿œå ããŸããvisit()
ã¡ãœããã¯ãASTã®ãã©ããŒã¹ãéå§ããŸãã
äŸïŒãã¹ãŠã®å€æ°ä»£å ¥ã®æ€çŽ¢
import ast
class VariableAssignmentFinder(ast.NodeVisitor):
def __init__(self):
self.assignments = []
def visit_Assign(self, node):
for target in node.targets:
if isinstance(target, ast.Name):
self.assignments.append(target.id)
code = """
x = 10
y = x + 5
message = "hello"
"""
ast_tree = ast.parse(code)
finder = VariableAssignmentFinder()
finder.visit(ast_tree)
print(finder.assignments) # Output: ['x', 'y', 'message']
ãã®äŸã§ã¯ãã³ãŒãå
ã®ãã¹ãŠã®å€æ°ä»£å
¥ãæ€çŽ¢ããŸããvisit_Assign
ã¡ãœããã¯ãå代å
¥ã¹ããŒãã¡ã³ãã«å¯ŸããŠåŒã³åºãããŸãã代å
¥ã®ã¿ãŒã²ãããå埩åŠçããã¿ãŒã²ãããåçŽãªååïŒast.Name
ïŒã§ããå Žåãååãassignments
ãªã¹ãã«è¿œå ããŸãã
ASTã®ä¿®æ£
ast
ã¢ãžã¥ãŒã«ã§ã¯ãASTãä¿®æ£ããããšãã§ããŸããæ¢åã®ããŒãã倿Žããããæ°ããããŒãã远å ããããããŒããå®å
šã«åé€ãããã§ããŸããASTãä¿®æ£ããã«ã¯ãast.NodeTransformer
ã¯ã©ã¹ã䜿çšããŸããast.NodeVisitor
ãšåæ§ã«ãast.NodeTransformer
ããµãã¯ã©ã¹åãããã®ã¡ãœããããªãŒããŒã©ã€ãããŠãç¹å®ã®ããŒãã¿ã€ããä¿®æ£ããŸããäž»ãªéãã¯ãast.NodeTransformer
ã¡ãœããã¯ãä¿®æ£ãããããŒãïŒãŸãã¯ããã眮ãæããæ°ããããŒãïŒãè¿ãå¿
èŠãããããšã§ããã¡ãœãããNone
ãè¿ããšãããŒãã¯ASTããåé€ãããŸãã
ASTãä¿®æ£ããããcompile()
颿°ã䜿çšããŠãå®è¡å¯èœãªPythonã³ãŒãã«ã³ã³ãã€ã«ãçŽãå¿
èŠããããŸãã
import ast
class AddOneTransformer(ast.NodeTransformer):
def visit_Num(self, node):
return ast.Num(n=node.n + 1)
code = """
x = 10
y = 20
"""
ast_tree = ast.parse(code)
transformer = AddOneTransformer()
new_ast_tree = transformer.visit(ast_tree)
new_code = compile(new_ast_tree, '', 'exec')
# Execute the modified code
exec(new_code)
print(x) # Output: 11
print(y) # Output: 21
ãã®äŸã§ã¯ãAddOneTransformer
ã¯ast.NodeTransformer
ããç¶æ¿ããvisit_Num
ã¡ãœããããªãŒããŒã©ã€ãããŸãããã®ã¡ãœããã¯ãåæ°å€ãªãã©ã«ããŒãïŒast.Num
ïŒã«å¯ŸããŠåŒã³åºãããŸãããã®ã¡ãœããã¯ãå€ã1ã ãã€ã³ã¯ãªã¡ã³ãããæ°ããast.Num
ããŒããäœæããŸããvisit()
ã¡ãœããã¯ãä¿®æ£ãããASTãè¿ããŸãã
compile()
颿°ã¯ãä¿®æ£ãããASTããã¡ã€ã«åïŒãã®å Žåã¯<string>
ãã³ãŒããæååããæ¥ãŠããããšã瀺ããŸãïŒãããã³å®è¡ã¢ãŒãïŒã³ãŒãã®ãããã¯ãå®è¡ããããã®'exec'
ïŒãåãåããŸããexec()
颿°ã䜿çšããŠå®è¡ã§ããã³ãŒããªããžã§ã¯ããè¿ããŸãã
äŸïŒå€æ°åã®çœ®æ
import ast
class VariableNameReplacer(ast.NodeTransformer):
def __init__(self, old_name, new_name):
self.old_name = old_name
self.new_name = new_name
def visit_Name(self, node):
if node.id == self.old_name:
return ast.Name(id=self.new_name, ctx=node.ctx)
return node
code = """
def multiply_by_two(number):
return number * 2
result = multiply_by_two(5)
print(result)
"""
ast_tree = ast.parse(code)
replacer = VariableNameReplacer('number', 'num')
new_ast_tree = replacer.visit(ast_tree)
new_code = compile(new_ast_tree, '', 'exec')
# Execute the modified code
exec(new_code)
ãã®äŸã§ã¯ã倿°å'number'
ã®ãã¹ãŠã®åºçŸç®æã'num'
ã«çœ®ãæããŸããVariableNameReplacer
ã¯ãå€ãååãšæ°ããååãåŒæ°ãšããŠåãåããŸããvisit_Name
ã¡ãœããã¯ãåååããŒãã«å¯ŸããŠåŒã³åºãããŸããããŒãã®èå¥åãå€ãååãšäžèŽããå Žåãæ°ããååãšåãã³ã³ããã¹ãïŒnode.ctx
ïŒãæã€æ°ããast.Name
ããŒããäœæããŸããã³ã³ããã¹ãã¯ãååã®äœ¿ç𿹿³ïŒäŸïŒããŒããæ ŒçŽïŒã瀺ããŸãã
ASTããã®ã³ãŒãçæ
compile()
ã䜿çšãããšãASTããã³ãŒããå®è¡ã§ããŸãããã³ãŒããæååãšããŠååŸããæ¹æ³ã¯æäŸãããŠããŸãããASTããPythonã³ãŒããçæããã«ã¯ãastunparse
ã©ã€ãã©ãªã䜿çšã§ããŸãããã®ã©ã€ãã©ãªã¯æšæºã©ã€ãã©ãªã®äžéšã§ã¯ãªããããæåã«ã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã
pip install astunparse
次ã«ãastunparse.unparse()
颿°ã䜿çšããŠãASTããã³ãŒããçæã§ããŸãã
import ast
import astunparse
code = """
def add(x, y):
return x + y
"""
ast_tree = ast.parse(code)
generated_code = astunparse.unparse(ast_tree)
print(generated_code)
åºåã¯æ¬¡ã®ããã«ãªããŸãã
def add(x, y):
return (x + y)
泚ïŒ(x + y)
ã®åšãã®æ¬åŒ§ã¯ãæ£ããæŒç®åã®åªå
é äœãä¿èšŒããããã«astunparse
ã«ãã£ãŠè¿œå ãããŸãããããã®æ¬åŒ§ã¯å³å¯ã«ã¯å¿
èŠãªããããããŸããããã³ãŒãã®æ£ãããä¿èšŒããŸãã
äŸïŒåçŽãªã¯ã©ã¹ã®çæ
import ast
import astunparse
class_name = 'MyClass'
method_name = 'my_method'
# Create the class definition node
class_def = ast.ClassDef(
name=class_name,
bases=[],
keywords=[],
body=[
ast.FunctionDef(
name=method_name,
args=ast.arguments(
posonlyargs=[],
args=[],
kwonlyargs=[],
kw_defaults=[],
defaults=[]
),
body=[
ast.Pass()
],
decorator_list=[],
returns=None,
type_comment=None
)
],
decorator_list=[]
)
# Create the module node containing the class definition
module = ast.Module(body=[class_def], type_ignores=[])
# Generate the code
code = astunparse.unparse(module)
print(code)
ãã®äŸã§ã¯ã次ã®Pythonã³ãŒããçæããŸãã
class MyClass:
def my_method():
pass
ããã¯ãASTãæåããæ§ç¯ããããããã³ãŒããçæããæ¹æ³ã瀺ããŠããŸãããã®ã¢ãããŒãã¯ãã³ãŒãçæããŒã«ãšã¡ã¿ããã°ã©ãã³ã°ã«åŒ·åã§ãã
ast
ã¢ãžã¥ãŒã«ã®å®çšçãªã¢ããªã±ãŒã·ã§ã³
ast
ã¢ãžã¥ãŒã«ã«ã¯ã次ã®ãããªå€ãã®å®çšçãªã¢ããªã±ãŒã·ã§ã³ããããŸãã
- ã³ãŒãåæïŒã¹ã¿ã€ã«éåãã»ãã¥ãªãã£è匱æ§ããŸãã¯ããã©ãŒãã³ã¹ããã«ããã¯ã«ã€ããŠã³ãŒããåæããŸããããšãã°ãå€§èŠæš¡ãªãããžã§ã¯ãå šäœã§ã³ãŒãã£ã³ã°æšæºãé©çšããããŒã«ãäœæã§ããŸãã
- èªåãªãã¡ã¯ã¿ãªã³ã°ïŒå€æ°ã®åå倿Žãã¡ãœããã®æœåºããŸãã¯ã³ãŒãã倿ããŠæ°ããèšèªæ©èœã䜿çšãããªã©ãã¿ã¹ã¯ãèªååããŸãã
rope
ã®ãããªããŒã«ã¯ã匷åãªãªãã¡ã¯ã¿ãªã³ã°æ©èœã®ããã«ASTãæŽ»çšããŸãã - éçåæïŒã³ãŒããå®éã«å®è¡ããã«ãæœåšçãªãšã©ãŒãŸãã¯ãã°ãç¹å®ããŸãã
pylint
ãflake8
ã®ãããªããŒã«ã¯ãASTåæã䜿çšããŠåé¡ãæ€åºããŸãã - ã³ãŒãçæïŒãã³ãã¬ãŒããŸãã¯ä»æ§ã«åºã¥ããŠã³ãŒããèªåçã«çæããŸããããã¯ãå埩çãªã³ãŒããäœæããããããŸããŸãªãã©ãããã©ãŒã çšã®ã³ãŒããçæãããããã®ã«åœ¹ç«ã¡ãŸãã
- èšèªæ¡åŒµïŒPythonã³ãŒããç°ãªã衚çŸã«å€æããããšã«ãããã«ã¹ã¿ã èšèªæ¡åŒµãŸãã¯ãã¡ã€ã³åºæèšèªïŒDSLïŒãäœæããŸãã
- ã»ãã¥ãªãã£ç£æ»ïŒæœåšçã«æå®³ãªæ§é ãŸãã¯è匱æ§ã«ã€ããŠã³ãŒããåæããŸããããã¯ãå®å šã§ãªãã³ãŒãã£ã³ã°ãã©ã¯ãã£ã¹ãç¹å®ããããã«äœ¿çšã§ããŸãã
äŸïŒã³ãŒãã£ã³ã°ã¹ã¿ã€ã«ã®é©çš
ãããžã§ã¯ãå
ã®ãã¹ãŠã®é¢æ°åãsnake_caseèŠåïŒäŸïŒmy_function
ã®ä»£ããã«myFunction
ïŒã«åŸãããã«ããããšããŸããast
ã¢ãžã¥ãŒã«ã䜿çšããŠãéåããã§ãã¯ã§ããŸãã
import ast
import re
class SnakeCaseChecker(ast.NodeVisitor):
def __init__(self):
self.errors = []
def visit_FunctionDef(self, node):
if not re.match(r'^[a-z]+(_[a-z]+)*$', node.name):
self.errors.append(f"Function name '{node.name}' does not follow snake_case convention")
def check_code(self, code):
ast_tree = ast.parse(code)
self.visit(ast_tree)
return self.errors
# Example usage
code = """
def myFunction(x):
return x * 2
def calculate_area(width, height):
return width * height
"""
checker = SnakeCaseChecker()
errors = checker.check_code(code)
if errors:
for error in errors:
print(error)
else:
print("No style violations found")
ãã®ã³ãŒãã¯ãast.NodeVisitor
ããç¶æ¿ããSnakeCaseChecker
ã¯ã©ã¹ãå®çŸ©ããŸããvisit_FunctionDef
ã¡ãœããã¯ã颿°åãsnake_caseæ£èŠè¡šçŸãšäžèŽãããã©ããããã§ãã¯ããŸããããã§ãªãå Žåããšã©ãŒã¡ãã»ãŒãžãerrors
ãªã¹ãã«è¿œå ããŸããcheck_code
ã¡ãœããã¯ãã³ãŒããè§£æããASTããã©ããŒã¹ãããšã©ãŒã®ãªã¹ããè¿ããŸãã
ast
ã¢ãžã¥ãŒã«ã䜿çšããéã®ãã¹ããã©ã¯ãã£ã¹
- ASTæ§é ãçè§£ããïŒASTãæäœããåã«ã
ast.dump()
ã䜿çšããŠãã®æ§é ãçè§£ããŠãã ãããããã«ãããæäœããå¿ èŠãããããŒããç¹å®ããã®ã«åœ¹ç«ã¡ãŸãã ast.NodeVisitor
ãšast.NodeTransformer
ã䜿çšããïŒãããã®ã¯ã©ã¹ã¯ãããªãŒãæåã§ããã²ãŒãããªããŠããASTããã©ããŒã¹ããã³ä¿®æ£ããããã®äŸ¿å©ãªæ¹æ³ãæäŸããŸãã- 培åºçã«ãã¹ãããïŒASTãä¿®æ£ãããšãã¯ã倿Žãæ£ããããšã©ãŒãçºçããªãããšã確èªããããã«ãã³ãŒãã培åºçã«ãã¹ãããŠãã ããã
- ã³ãŒãçæã«ã¯
astunparse
ãæ€èšããïŒcompile()
ã¯ä¿®æ£ãããã³ãŒãã®å®è¡ã«åœ¹ç«ã¡ãŸãããastunparse
ã¯ASTããèªã¿ãããPythonã³ãŒããçæããæ¹æ³ãæäŸããŸãã - åãã³ãã䜿çšããïŒåãã³ãã¯ãç¹ã«è€éãªASTæ§é ãæ±ãå Žåã«ãã³ãŒãã®å¯èªæ§ãšä¿å®æ§ãå€§å¹ ã«åäžãããããšãã§ããŸãã
- ã³ãŒããææžåããïŒã«ã¹ã¿ã ASTããžã¿ãŒãŸãã¯ãã©ã³ã¹ãã©ãŒããŒãäœæããå Žåã¯ãåã¡ãœããã®ç®çãšãã®ASTãžã®å€æŽãæç¢ºã«èª¬æããããã«ãã³ãŒããææžåããŠãã ããã
課é¡ãšèæ ®äºé
- è€éãïŒç¹ã«å€§èŠæš¡ãªã³ãŒãããŒã¹ã®å ŽåãASTã®æäœã¯è€éã«ãªãå¯èœæ§ããããŸããç°ãªãããŒãã¿ã€ããšãã®é¢ä¿ãçè§£ããã®ã¯å°é£ãªå ŽåããããŸãã
- ã¡ã³ããã³ã¹ïŒASTæ§é ã¯Pythonã®ããŒãžã§ã³éã§å€æŽãããå¯èœæ§ããããŸããç°ãªãPythonããŒãžã§ã³ã§ã³ãŒãããã¹ãããŠãäºææ§ã確èªããŠãã ããã
- ããã©ãŒãã³ã¹ïŒå€§èŠæš¡ãªASTã®ãã©ããŒã¹ãšä¿®æ£ã¯é ããªãå¯èœæ§ããããŸããã³ãŒããæé©åããŠããã©ãŒãã³ã¹ãåäžãããããšãæ€èšããŠãã ãããé »ç¹ã«ã¢ã¯ã»ã¹ãããããŒãããã£ãã·ã¥ããããããå¹ççãªã¢ã«ãŽãªãºã ã䜿çšããããããšåœ¹ç«ã¡ãŸãã
- ãšã©ãŒåŠçïŒASTãè§£æãŸãã¯æäœãããšãã«ããšã©ãŒãé©åã«åŠçããŸãããŠãŒã¶ãŒã«æçãªãšã©ãŒã¡ãã»ãŒãžãæäŸããŸãã
- ã»ãã¥ãªãã£ïŒASTããçæãããã³ãŒããå®è¡ãããšãã¯ãç¹ã«ASTããŠãŒã¶ãŒå ¥åã«åºã¥ããŠããå Žåã¯æ³šæããŠãã ãããã³ãŒãã€ã³ãžã§ã¯ã·ã§ã³æ»æãé²ãããã«ãå ¥åããµãã¿ã€ãºããŸãã
çµè«
Pythonã®ast
ã¢ãžã¥ãŒã«ã¯ãPythonã³ãŒãã®æœè±¡æ§ææšãæäœãã匷åã§æè»ãªæ¹æ³ãæäŸããŸããASTæ§é ãçè§£ããast.NodeVisitor
ã¯ã©ã¹ãšast.NodeTransformer
ã¯ã©ã¹ã䜿çšããããšã§ãPythonã³ãŒããããã°ã©ã ã§åæãä¿®æ£ãããã³çæã§ããŸããããã«ãããã³ãŒãåæããŒã«ããèªåãªãã¡ã¯ã¿ãªã³ã°ãããã«ã¯ã«ã¹ã¿ã èšèªæ¡åŒµãŸã§ãå¹
åºãã¢ããªã±ãŒã·ã§ã³ãžã®æãéãããŸããASTã®æäœã¯è€éã«ãªãå¯èœæ§ããããŸãããã³ãŒããããã°ã©ã ã§æäœã§ããããšã®å©ç¹ã¯å€§ããã§ããast
ã¢ãžã¥ãŒã«ã®åãæŽ»çšããŠãPythonãããžã§ã¯ãã®æ°ããªå¯èœæ§ãè§£ãæŸã¡ãŸãããã